package com.punch.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.punch.common.dto.system.dict.DictDTO;
import com.punch.common.dto.system.dict.DictKeyDTO;
import com.punch.common.exception.BusinessException;
import com.punch.common.page.PageInfo;
import com.punch.common.tools.BasePage;
import com.punch.common.vo.system.dict.PageDictVO;
import com.punch.system.exception.SysExceptionEnum;
import com.punch.system.mapper.SysDictKeyMapper;
import com.punch.system.model.SysDict;
import com.punch.system.model.SysDictKey;
import com.punch.system.query.DictQueryInfo;
import com.punch.system.service.DictKeyService;
import com.punch.system.service.DictService;
import com.punch.system.util.DictUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * DictKeyServiceImpl-数据字典key 服务实现类
 *
 * @author wujj
 * @version 1.0.0
 * @since 2020/6/3 20:01
 */
@Service
public class DictKeyServiceImpl extends ServiceImpl<SysDictKeyMapper, SysDictKey> implements DictKeyService {

    @Autowired
    private DictService dictService;

    /**
     * 系统下字典类型列表
     *
     * @param queryInfo 查询条件
     * @return PageInfo<PageDictVO>
     */
    @Override
    public PageInfo<PageDictVO> queryPage(DictQueryInfo queryInfo) {
        return BasePage.queryBasePage(queryInfo, params -> this.getBaseMapper().queryCount(params),
                params -> this.getBaseMapper().queryList(params));
    }

    /**
     * 保存数据字典类型
     *
     * @param dictKeyDTO 资源数据字典类型表单
     * @return dictKeyId
     * @author wujj
     * @since 2020/6/4 14:31
     */
    @Override
    public Long saveDictKey(DictKeyDTO dictKeyDTO) {
        //重名检查
        dictKeyRepeatCheck(dictKeyDTO.getDictKey(), 0L);
        SysDictKey sysDictKey = new SysDictKey();
        BeanUtils.copyProperties(dictKeyDTO, sysDictKey);
        //  sysDictKey.setCreateName(UserUtil.getUser().getUserName());
        if (!save(sysDictKey)) {
            throw new BusinessException(SysExceptionEnum.DATA_INSERT_EXCEPTION);
        }
        return sysDictKey.getId();
    }

    /**
     * 修改数据字典类型
     *
     * @param dictKeyDTO 资源数据字典类型表单
     * @return dictKeyId
     * @author wujj
     * @since 2020/6/4 14:35
     */
    @Override
    public Long updateDictKey(DictKeyDTO dictKeyDTO) {
        //重名检查
        dictKeyRepeatCheck(dictKeyDTO.getDictKey(), dictKeyDTO.getDictKeyId());
        SysDictKey sysDictKeyEX = getById(dictKeyDTO.getDictKeyId());
        //启用状态不能删除
        if (sysDictKeyEX == null) {
            throw new BusinessException(SysExceptionEnum.DICT_NOT_EXIST);
        }
        SysDictKey sysDictKey = new SysDictKey();
        BeanUtils.copyProperties(dictKeyDTO, sysDictKey);
        sysDictKey.setId(dictKeyDTO.getDictKeyId());
        if (!updateById(sysDictKey)) {
            throw new BusinessException(SysExceptionEnum.DATA_UPDATE_EXCEPTION);
        }
        //如果key发生变化,sys_dict表更新dict_key
        if (!sysDictKeyEX.getDictKey().equals(dictKeyDTO.getDictKey())) {
            QueryWrapper<SysDict> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(SysDict::getKeyId, dictKeyDTO.getDictKeyId());
            List<SysDict> list = dictService.list(queryWrapper);
            //重新设置key值
            for (SysDict sysDict : list) {
                sysDict.setDictKey(dictKeyDTO.getDictKey());
            }
            dictService.saveOrUpdateBatch(list);
            //删除redis数据
            DictUtil.delSysDictList(sysDictKeyEX.getDictKey());
            //存入redis中
            DictUtil.putSysDict(dictKeyDTO.getDictKey());
        }
        return sysDictKey.getId();
    }

    /**
     * 删除数据字典类型
     *
     * @param dictKeyId 资源数据字典类型id
     * @return dictKeyId
     * @author wujj
     * @since 2020/6/4 14:38
     */
    @Override
    public Long deleteDictKey(Long dictKeyId) {
        SysDictKey sysDictKeyEX = getById(dictKeyId);
        //启用状态不能删除
        if (sysDictKeyEX == null) {
            throw new BusinessException(SysExceptionEnum.DICT_NOT_EXIST);
        }
        if (1 == sysDictKeyEX.getStatus()) {
            throw new BusinessException(SysExceptionEnum.DICT_ON_USE);
        }
        if (!removeById(dictKeyId)) {
            throw new BusinessException(SysExceptionEnum.DATA_DELETION_EXCEPTION);
        }
        //删除字典值表数据
        UpdateWrapper<SysDict> deleteWrapper = new UpdateWrapper<>();
        deleteWrapper.lambda().eq(SysDict::getDictKey, sysDictKeyEX.getDictKey());
        dictService.remove(deleteWrapper);
        //删除redis表数据
        DictUtil.delSysDictList(sysDictKeyEX.getDictKey());
        return dictKeyId;
    }

    /**
     * 启用/停用数据字典
     *
     * @param dictKeyId 资源数据字典类型id
     * @return dictKeyId
     * @author wujj
     * @since 2020/6/4 14:38
     */
    @Override
    public Long updateDictKeyStatus(Long dictKeyId) {
        SysDictKey sysDictKeyEX = getById(dictKeyId);
        //启用状态不能删除
        if (sysDictKeyEX == null) {
            throw new BusinessException(SysExceptionEnum.DICT_NOT_EXIST);
        }
        SysDictKey sysDictKey = new SysDictKey();
        //停用状态-->变成启用
        if (0 == sysDictKeyEX.getStatus()) {
            //没有数据的不能启用
            List<DictDTO> list = dictService.listDictByKey(dictKeyId);
            if (CollUtil.isEmpty(list)) {
                throw new BusinessException(SysExceptionEnum.DICT_NO_VALUE);
            }
            sysDictKey.setStatus(1);
        }
        //启用状态-->变成停用
        if (1 == sysDictKeyEX.getStatus()) {
            sysDictKey.setStatus(0);
            //删除redis数据
            DictUtil.delSysDictList(sysDictKeyEX.getDictKey());
        }
        sysDictKey.setId(dictKeyId);
        updateById(sysDictKey);
        return dictKeyId;
    }

    /**
     * 数据重复校验
     *
     * @param dictKey   key
     * @param dictKeyId 主键id
     * @author wujj
     * @since 2020/6/8 14:43
     */
    private void dictKeyRepeatCheck(String dictKey, Long dictKeyId) {
        //校验同级地区名是否重复
        QueryWrapper<SysDictKey> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysDictKey::getDictKey, dictKey);
        if (!dictKeyId.equals(0L)) {
            queryWrapper.lambda().notIn(SysDictKey::getId, dictKeyId);
        }
        if (count(queryWrapper) > 0) {
            throw new BusinessException(SysExceptionEnum.DICT_KEY_REPEAT);
        }
    }
}
